// universal_paste.cpp
// Ctrl+Enter 将剪贴板文本注入到目标窗口（ANSI/Unicode均可），找不到控件则模拟Ctrl+V。

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <string>
#include <vector>

#pragma comment(lib, "user32.lib")

// ===== 配置区 =====
static const wchar_t* kMainClassW = L"Notepad++"; // 主窗口类名
static const wchar_t* kChildClassW = L"Scintilla"; // 子编辑控件类名（War3可留空）
// =================

std::wstring GetClipboardUnicodeText() 
{
    if (!OpenClipboard(nullptr)) 
        return L"";

    HANDLE hData = GetClipboardData(CF_UNICODETEXT);
    if (!hData) 
    { 
        CloseClipboard(); 
        return L""; 
    }

    LPCWSTR pText = static_cast<LPCWSTR>(GlobalLock(hData));
    std::wstring result;
    if (pText) 
        result = pText;

    GlobalUnlock(hData);
    CloseClipboard();
    return result;
}

std::string WideToGBK(const std::wstring& w) 
{
    if (w.empty()) 
        return {};

    int cb = WideCharToMultiByte(936, 0, w.c_str(), (int)w.size(), nullptr, 0, nullptr, nullptr);
    std::string out(cb, '\0');
    WideCharToMultiByte(936, 0, w.c_str(), (int)w.size(), (LPSTR)out.data(), cb, nullptr, nullptr);
    return out;
}

HWND FindTargetWindow() 
{
    HWND hwndMain = FindWindowW(kMainClassW, nullptr);
    if (!hwndMain) 
        return nullptr;

    if (kChildClassW && *kChildClassW) 
    {
        HWND hwndChild = FindWindowExW(hwndMain, nullptr, kChildClassW, nullptr);
        if (hwndChild) return hwndChild;
    }
    return hwndMain;
}

void FocusWindow(HWND hwnd) 
{
    SetForegroundWindow(hwnd);
    SetFocus(hwnd);
    Sleep(10);
}

void SendUnicodeText(HWND hwnd, const std::wstring& text) 
{
    for (wchar_t ch : text) 
    {
        SendMessageW(hwnd, WM_CHAR, (WPARAM)ch, 1);
        Sleep(1);
    }
}

void SendAnsiText(HWND hwnd, const std::string& text) 
{
    for (unsigned char ch : text) 
    {
        SendMessageA(hwnd, WM_CHAR, (WPARAM)ch, 1);
        Sleep(1);
    }
}

void SimulateCtrlV() 
{
    keybd_event(VK_CONTROL, 0, 0, 0);
    keybd_event('V', 0, 0, 0);
    keybd_event('V', 0, KEYEVENTF_KEYUP, 0);
    keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
}

int WINAPI wWinMain(HINSTANCE, HINSTANCE, PWSTR, int) 
{
    if (!RegisterHotKey(nullptr, 1, MOD_CONTROL | MOD_NOREPEAT, VK_RETURN)) 
    {
        MessageBoxW(nullptr, L"注册热键失败", L"paste", MB_ICONERROR);
        return 1;
    }

    MSG msg;
    while (GetMessageW(&msg, nullptr, 0, 0)) 
    {
        if (msg.message == WM_HOTKEY && msg.wParam == 1) 
        {
            HWND hwnd = FindTargetWindow();
            if (!hwnd) 
            { 
                MessageBeep(MB_ICONHAND); 
                continue; 
            }
            FocusWindow(hwnd);

            std::wstring utext = GetClipboardUnicodeText();
            if (utext.empty()) 
            { 
                MessageBeep(MB_ICONWARNING); 
                continue; 
            }

            if (IsWindowUnicode(hwnd)) 
            {
                SendUnicodeText(hwnd, utext);
            }
            else 
            {
                std::string gbk = WideToGBK(utext);
                if (!gbk.empty()) 
                    SendAnsiText(hwnd, gbk);
                else 
                    SimulateCtrlV();
            }
        }
        else 
        {
            TranslateMessage(&msg);
            DispatchMessageW(&msg);
        }
    }
    UnregisterHotKey(nullptr, 1);
    return 0;
}
